package cn.xiaolang.function.network.multiplexing;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author Dean
 * @date 2022-02-13
 */
public class ReadState implements HandlerState {

    private SelectionKey sk;

    @Override
    public void changeState(TCPHandler h) {
        h.setState(new WorkState());
    }

    @Override
    public void handle(TCPHandler h, SelectionKey sk, SocketChannel sc,
                       ThreadPoolExecutor pool) throws IOException {
        // read()
        this.sk = sk;
        // non-blocking下不可用Readers，因为Readers不支持
        byte[] arr = new byte[1024];
        ByteBuffer buf = ByteBuffer.wrap(arr);
        if (sc.read(buf) == -1) {
            System.out.println("[Warning!] A client has been closed.");
            h.closeChannel();
            return;
        }

        String str = new String(arr);

        if (!str.equals(" ")) {
            // 改变状态(READING->WORKING)
            h.setState(new WorkState());
            // do process in worker thread
            pool.execute(new WorkerThread(h, str));
            System.out.println(sc.socket().getRemoteSocketAddress().toString() + " > " + str);
        }
    }


    synchronized void process(TCPHandler h, String str) {
        // do process(decode, logically process, encode)..
        // ..
        // 改变状态(WORKING->SENDING)
        h.setState(new WriteState());
        // 改变通道注册的事件
        this.sk.interestOps(SelectionKey.OP_WRITE);
        // 使一个阻塞住的selector操作立即返回
        this.sk.selector().wakeup();
    }


    class WorkerThread implements Runnable {

        TCPHandler h;
        String str;

        public WorkerThread(TCPHandler h, String str) {
            this.h = h;
            this.str = str;
        }

        @Override

        public void run() {
            process(h, str);
        }

    }

}

